One challenge in the virtualization of modern computer architectures is creation and maintenance of memory mapping information in a form often referred to as shadow page tables. In general, shadow page tables encode virtual-to-physical memory mappings usable by a memory management unit or other facility of underlying hardware in mapping memory access targets of instructions executed on behalf of a guest computation. Typically, the guest computation is aware of mappings to an apparent physical address space of a virtual machine, but is unaware of actual mappings to an address space in underlying physical memory.
Thus, while mappings encoded in shadow page tables can correspond to mappings maintained by a guest operating system in conventional page tables (e.g., guest page tables), they typically go at least one step further, completing the mapping to addresses in underlying physical memory. To understand why this further mapping is relevant, it is important to recognize that the guest operating system (or an execution context thereof) is typically not aware that it executes on a virtual machine. Accordingly, the guest operating system and its execution contexts maintain and view the guest page tables as representing operant virtual-to-physical memory mappings, even though the mapped-to “physical” addresses are really addresses in a space that is itself virtualized by the virtualization system. Such guest page table mappings can therefore be understood as mappings from Guest Virtual Page Numbers (GVPNs) to Guest Physical Page Numbers (GPPNs).
Since the guest operating system executes in a virtual machine, another layer of mapping (e.g., from a Guest Physical Page Number, GPPN, to a machine Physical Page Number, PPN) is typically provided by the virtualization system. Shadow page tables (and cached representations of entries thereof) provide an efficient mechanism for encoding mappings from GVPNs to PPNs and therefore allow the virtualization system to manage direct execution of guest code on underlying hardware, while avoiding (in most cases) a two-layer runtime mapping of memory addresses.
In some virtualization system implementations, coherence between shadow page tables and the guest page tables is assured by using page protection mechanisms to intercept guest writes to memory pages that contain guest page table information. A handler is used to service a resulting fault, updating a shadow page table entry (and the targeted guest page table entry) in correspondence with an intercepted guest write. Thereafter, control is returned to the execution context that generated the fault. Unfortunately, a coherence scheme that relies on page protection mechanisms in this way tends to introduce page fault overheads which are not present when executing on native hardware.
Improved and/or alternative methods are desired.